package edu.intprog.egreeting;

import java.io.IOException;
import java.util.List;

import javax.servlet.ServletException;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.hibernate.HibernateException;
import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.Transaction;


import edu.intprog.mail.BaseMailer;
import edu.intprog.mail.PasswordMailer;
import edu.intprog.sql.SessionManager;
import edu.intprog.egreeting.basic.EgreetingBaseServlet;
import edu.intprog.egreeting.beans.Messages;
import edu.intprog.egreeting.beans.UserDef;

/**
 * Servlet implementation class for Servlet: LoginServlet
 *
 */
public class LoginServlet extends EgreetingBaseServlet implements javax.servlet.Servlet {
	static final long serialVersionUID = 1L;

	/* (non-Java-doc)
	 * @see javax.servlet.http.HttpServlet#HttpServlet()
	 */
	public LoginServlet() {
		super();
	}   	
	
	/* (non-Java-doc)
	 * @see javax.servlet.http.HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
	 */
	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		//we get here on 2 occasions
		//1=logout button was pressed
		//2=hack attempt
		
		if (request.getParameter("logout")!=null)
		{	
			//logout button was pressed
			request.getSession().removeAttribute("user");
			Messages msgDef = new Messages();
			msgDef.set_infoMessage("Logout was successfull<br/>");
			request.setAttribute("msgs", msgDef);
			getServletContext().getRequestDispatcher("/StartServlet").forward(request, response);
		}
	}
	
	/* (non-Java-doc)
	 * @see javax.servlet.http.HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
	 */
	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		String email=request.getParameter("emailAddr");
		String password=request.getParameter("userPassword");
		
		Cookie c = new Cookie(StartServlet.cookieName,StartServlet.generateCookie(new String[]{email, password}));
	    
		if(request.getParameter("rememberMe")!=null)
		{
			//cookie was set to be saved with the email and password
		    c.setMaxAge(60*60*24*365);
		}
		else
		{
			//cookie should be removed
			c.setMaxAge(0);
		}
	    response.addCookie(c);
		
	    String errMessage = new String();
	    if (request.getParameter("login")!=null)
	    {
	    	errMessage = handleLogin(email, password, request);
	    	
			if (errMessage.length()==0)
			{
				getServletContext().getRequestDispatcher("/userMainMenu.jsp").forward(request, response);
				return;
			}
			else
			{
				//error was found - report it to the user
				Messages msgDef = new Messages();
				msgDef.set_errorMessage(errMessage);
				request.setAttribute("msgs", msgDef);
				getServletContext().getRequestDispatcher("/StartServlet").forward(request, response);
				return;
			}
	    }
	    if (request.getParameter("reminder")!=null)
	    {
	    	errMessage = handleRemindPassword(email, request);
	    	Messages msgDef = new Messages();
	    	if (errMessage.length()==0)
			{
				msgDef.set_infoMessage("Password reminder E-Mail was sent successfully");
			}
	    	else
	    	{
	    		msgDef.set_errorMessage(errMessage);
	    	}
			request.setAttribute("msgs", msgDef);
			getServletContext().getRequestDispatcher("/StartServlet").forward(request, response);
			return;
	    }
	}

	private String handleRemindPassword(String email, HttpServletRequest request) {
		String errMessage=new String();
		UserDef user = null;

		Transaction tx = null;
		Session session = SessionManager.getCurrentSession();
		try {
			//check to see if a user exist that has the given email and password combo
			tx = session.beginTransaction();
			Query query = session.createQuery("from edu.intprog.egreeting.beans.UserDef where EMAIL_ADDR='"+email+"'");
			@SuppressWarnings("unchecked")
			List<UserDef> result = (List<UserDef>) query.list();
			if(result.size()==1)
			{
				user = result.get(0);
			}
			else
			{
				//no such user exist that answer the email criteria
				errMessage = errMessage + "No such E-Mail is registered. Please enter your E-Mail address" +
						" before clicking the password reminder button, and your password will be sent to you.<br/>";
			}
			tx.commit();
		} catch (HibernateException e) {
			e.printStackTrace();
			if (tx != null && tx.isActive())
				tx.rollback();
			//sql error
			errMessage = errMessage + e.getMessage() + "<br/>";
		}
		
		if (errMessage.length()==0)
		{
			BaseMailer.initilizeMailConfigurationFromFile(request);
			PasswordMailer pm = new PasswordMailer(user.get_userPassword(), user.get_emailAddr());
			String thisClassName = this.getClass().getName();
			thisClassName = thisClassName.substring(thisClassName.lastIndexOf('.')+1);
			String startServletPath = request.getRequestURL().toString().replaceAll(thisClassName, "StartServlet");
			errMessage = pm.sendMail(startServletPath);
		}
		
		return errMessage;
	}

	private String handleLogin(String email, String password, HttpServletRequest request)
	{
		String errMessage=new String();
		UserDef user = null;

		Transaction tx = null;
		Session session = SessionManager.getCurrentSession();
		try {
			//check to see if a user exist that has the given email and password combo
			tx = session.beginTransaction();
			Query query = session.createQuery("from edu.intprog.egreeting.beans.UserDef where EMAIL_ADDR='"+email+"' and USER_PASSWORD='"+password+"'");
			@SuppressWarnings("unchecked")
			List<UserDef> result = (List<UserDef>) query.list();
			if(result.size()==1)
			{
				user = result.get(0);
				if (user.is_isActive() == false)
				{
					//if user was not activated, notify the user
					errMessage = errMessage + "E-Mail has not been activated yet. Please check your E-Mail for the activation mail " +
					"and click on the proper link.<br/>";
				}
				else
				{
					//everything is ok, add the logged user definition to the session
					request.getSession().setAttribute("user", user);
				}
			}
			else
			{
				//no such user exist that answer the email and password combo criteria
				errMessage = errMessage + "Bad E-Mail or Password.<br/>";
			}
			tx.commit();
		} catch (HibernateException e) {
			e.printStackTrace();
			if (tx != null && tx.isActive())
				tx.rollback();
			//sql error
			errMessage = errMessage + e.getMessage() + "<br/>";
		}
		
		return errMessage;
	}
}